Add more version and capability reporting to Xen. Print the results with 'xm info'.
authoriap10@freefall.cl.cam.ac.uk <iap10@freefall.cl.cam.ac.uk>
Fri, 9 Sep 2005 15:33:32 +0000 (15:33 +0000)
committeriap10@freefall.cl.cam.ac.uk <iap10@freefall.cl.cam.ac.uk>
Fri, 9 Sep 2005 15:33:32 +0000 (15:33 +0000)
Signed-off-by: ian@xensource.com
tools/python/xen/lowlevel/xc/xc.c
tools/python/xen/xend/XendNode.py
xen/arch/x86/dom0_ops.c
xen/arch/x86/setup.c
xen/arch/x86/vmx.c
xen/common/kernel.c
xen/include/public/dom0_ops.h
xen/include/public/version.h

index 531b7a7b1c486fac73414076279b5af087a86ed5..113a57b2f9403e9c3d8cbe415277bbf5701be105 100644 (file)
@@ -690,6 +690,8 @@ static PyObject *pyxc_physinfo(PyObject *self,
 {
     XcObject *xc = (XcObject *)self;
     xc_physinfo_t info;
+    char cpu_cap[128], *p=cpu_cap, *q=cpu_cap;
+    int i;
     
     if ( !PyArg_ParseTuple(args, "") )
         return NULL;
@@ -697,14 +699,25 @@ static PyObject *pyxc_physinfo(PyObject *self,
     if ( xc_physinfo(xc->xc_handle, &info) != 0 )
         return PyErr_SetFromErrno(xc_error);
 
-    return Py_BuildValue("{s:i,s:i,s:i,s:i,s:l,s:l,s:i}",
+    *q=0;
+    for(i=0;i<sizeof(info.hw_cap)/4;i++)
+    {
+        p+=sprintf(p,"%08x:",info.hw_cap[i]);
+        if(info.hw_cap[i])
+           q=p;
+    }
+    if(q>cpu_cap)
+        *(q-1)=0;
+
+    return Py_BuildValue("{s:i,s:i,s:i,s:i,s:l,s:l,s:i,s:s}",
                          "threads_per_core", info.threads_per_core,
                          "cores_per_socket", info.cores_per_socket,
                          "sockets_per_node", info.sockets_per_node,
                          "nr_nodes",         info.nr_nodes,
                          "total_pages",      info.total_pages,
                          "free_pages",       info.free_pages,
-                         "cpu_khz",          info.cpu_khz);
+                         "cpu_khz",          info.cpu_khz,
+                         "hw_caps",          cpu_cap);
 }
 
 static PyObject *pyxc_xeninfo(PyObject *self,
@@ -715,7 +728,10 @@ static PyObject *pyxc_xeninfo(PyObject *self,
     xen_extraversion_t xen_extra;
     xen_compile_info_t xen_cc;
     xen_changeset_info_t xen_chgset;
+    xen_capabilities_info_t xen_caps;
+    xen_parameters_info_t xen_parms;
     long xen_version;
+    char str[128];
 
     xen_version = xc_version(xc->xc_handle, XENVER_version, NULL);
 
@@ -728,10 +744,20 @@ static PyObject *pyxc_xeninfo(PyObject *self,
     if ( xc_version(xc->xc_handle, XENVER_changeset, &xen_chgset) != 0 )
         return PyErr_SetFromErrno(xc_error);
 
-    return Py_BuildValue("{s:i,s:i,s:s,s:s,s:s,s:s,s:s,s:s}",
+    if ( xc_version(xc->xc_handle, XENVER_capabilities, &xen_caps) != 0 )
+        return PyErr_SetFromErrno(xc_error);
+
+    if ( xc_version(xc->xc_handle, XENVER_parameters, &xen_parms) != 0 )
+        return PyErr_SetFromErrno(xc_error);
+
+    sprintf(str,"virt_start=0x%lx",xen_parms.virt_start);
+
+    return Py_BuildValue("{s:i,s:i,s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:s}",
                          "xen_major", xen_version >> 16,
                          "xen_minor", (xen_version & 0xffff),
                          "xen_extra", xen_extra,
+                         "xen_caps",  xen_caps.caps,
+                         "xen_params", str,
                          "xen_changeset", xen_chgset,
                          "cc_compiler", xen_cc.compiler,
                          "cc_compile_by", xen_cc.compile_by,
index 859d39d31f4a24bf1a1978f564b6751931c6e420..d8eba55d4cc1c39f80d4c98769baab7b2f1fcf06 100644 (file)
@@ -58,20 +58,26 @@ class XendNode:
 
     def physinfo(self):
         pinfo = self.xc.physinfo()
-        info = [['cores_per_socket', pinfo['cores_per_socket']],
+        info = [['nr_cpus',          pinfo['nr_nodes']*pinfo['sockets_per_node']*pinfo['cores_per_socket']*pinfo['threads_per_core']],
+                ['nr_nodes',         pinfo['nr_nodes']],
+                ['sockets_per_node', pinfo['sockets_per_node']],
+                ['cores_per_socket', pinfo['cores_per_socket']],
                 ['threads_per_core', pinfo['threads_per_core']],
-                ['cpu_mhz', pinfo['cpu_khz']/1000],
-                ['memory', pinfo['total_pages']/256],
-                ['free_memory', pinfo['free_pages']/256]]
+                ['cpu_mhz',          pinfo['cpu_khz']/1000],
+                ['hw_caps',          pinfo['hw_caps']],
+                ['memory',           pinfo['total_pages']/256],
+                ['free_memory',      pinfo['free_pages']/256]]
         return info
         
     def xeninfo(self):
         xinfo = self.xc.xeninfo()
-       return [['xen_major', xinfo['xen_major']],
-               ['xen_minor', xinfo['xen_minor']],
-               ['xen_extra', xinfo['xen_extra']],
-               ['xen_changeset', xinfo['xen_changeset']],
-               ['cc_compiler', xinfo['cc_compiler']],
+        return [['xen_major', xinfo['xen_major']],
+                ['xen_minor', xinfo['xen_minor']],
+                ['xen_extra', xinfo['xen_extra']],
+                ['xen_caps',  xinfo['xen_caps']],
+                ['xen_params',xinfo['xen_params']],
+                ['xen_changeset', xinfo['xen_changeset']],
+                ['cc_compiler', xinfo['cc_compiler']],
                 ['cc_compile_by', xinfo['cc_compile_by']],
                 ['cc_compile_domain', xinfo['cc_compile_domain']],
                 ['cc_compile_date', xinfo['cc_compile_date']]]
index 06562059c406b2fbf07966997042424601585420..936120dcad4e330afeb0e674581d66f76c8a33b3 100644 (file)
@@ -19,6 +19,7 @@
 #include <xen/console.h>
 #include <asm/shadow.h>
 #include <asm/irq.h>
+#include <asm/processor.h>
 #include <public/sched_ctl.h>
 
 #include <asm/mtrr.h>
@@ -188,9 +189,11 @@ long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op)
         pi->total_pages      = max_page;
         pi->free_pages       = avail_domheap_pages();
         pi->cpu_khz          = cpu_khz;
-
-        copy_to_user(u_dom0_op, op, sizeof(*op));
+        memset( pi->hw_cap, 0, sizeof(pi->hw_cap) );
+        memcpy( pi->hw_cap, boot_cpu_data.x86_capability, NCAPINTS*4 );
         ret = 0;
+        if( copy_to_user(u_dom0_op, op, sizeof(*op)) )
+           ret = -EINVAL;
     }
     break;
     
index 6c5adf5ca0ea3f2ff8e1476d1def767e89d337e2..8ce28cbed40e4308d0d82a3f0718c5205f1b371e 100644 (file)
@@ -12,6 +12,8 @@
 #include <xen/trace.h>
 #include <xen/multiboot.h>
 #include <xen/domain_page.h>
+#include <xen/compile.h>
+#include <public/version.h>
 #include <asm/bitops.h>
 #include <asm/smp.h>
 #include <asm/processor.h>
@@ -91,6 +93,8 @@ unsigned long mmu_cr4_features = X86_CR4_PSE;
 #endif
 EXPORT_SYMBOL(mmu_cr4_features);
 
+int hvm_enabled = 0; /* can we run unmodified guests */
+
 struct vcpu *idle_task[NR_CPUS] = { &idle0_vcpu };
 
 int acpi_disabled;
@@ -529,6 +533,45 @@ void __init __start_xen(multiboot_info_t *mbi)
     startup_cpu_idle_loop();
 }
 
+void arch_get_xen_caps(xen_capabilities_info_t *info)
+{
+    char *p=info->caps;
+
+    *p=0;
+
+#ifdef CONFIG_X86_32
+
+#ifndef CONFIG_X86_PAE       
+    p+=sprintf(p,"xen_%d.%d_x86_32 ",XEN_VERSION,XEN_SUBVERSION);    
+    if(hvm_enabled)
+    {
+        p+=sprintf(p,"hvm_%d.%d_x86_32 ",XEN_VERSION,XEN_SUBVERSION);    
+    }
+#else
+    p+=sprintf(p,"xen_%d.%d_x86_32p ",XEN_VERSION,XEN_SUBVERSION);
+    if(hvm_enabled)
+    {
+        //p+=sprintf(p,"hvm_%d.%d_x86_32 ",XEN_VERSION,XEN_SUBVERSION);    
+        //p+=sprintf(p,"hvm_%d.%d_x86_32p ",XEN_VERSION,XEN_SUBVERSION);    
+    }
+
+#endif        
+
+#else /* !CONFIG_X86_32 */
+    p+=sprintf(p,"xen_%d.%d_x86_64 ",XEN_VERSION,XEN_SUBVERSION);
+    if(hvm_enabled)
+    {
+        //p+=sprintf(p,"hvm_%d.%d_x86_32 ",XEN_VERSION,XEN_SUBVERSION);    
+        //p+=sprintf(p,"hvm_%d.%d_x86_32p ",XEN_VERSION,XEN_SUBVERSION);    
+        p+=sprintf(p,"hvm_%d.%d_x86_64 ",XEN_VERSION,XEN_SUBVERSION);    
+    }
+#endif
+    
+    BUG_ON((p-info->caps)>sizeof(*info));
+
+    if(p>info->caps) *(p-1) = 0;
+}
+
 /*
  * Local variables:
  * mode: C
index 5cb4882b0a8ea22656c943caaca904c21b973570..94700d9b02631c0ee9412603f502e074127bb644 100644 (file)
@@ -50,6 +50,8 @@ int vmcs_size;
 unsigned int opt_vmx_debug_level = 0;
 integer_param("vmx_debug", opt_vmx_debug_level);
 
+extern int hvm_enabled;
+
 #ifdef TRACE_BUFFER
 static unsigned long trace_values[NR_CPUS][4];
 #define TRACE_VMEXIT(index,value) trace_values[current->processor][index]=value
@@ -345,6 +347,8 @@ int start_vmx(void)
 
     vmx_save_init_msrs();
 
+    hvm_enabled = 1;
+
     return 1;
 }
 
index d36dd8d5804129741cdc105b295419ab0ccf0cbe..82df04493d3e2693214ad2ea617f2e6191762be5 100644 (file)
@@ -113,16 +113,27 @@ long do_xen_version(int cmd, void *arg)
 
     case XENVER_capabilities:
     {
-        struct xen_capabilities_info info;
+        xen_capabilities_info_t info;
+        extern void arch_get_xen_caps(xen_capabilities_info_t * info);
         
-        /* FIXME */
-        info.arch = 0;
-        info.pae = 0;
+        memset(&info, 0, sizeof(info));
+        arch_get_xen_caps(&info);
+
         if ( copy_to_user(arg, &info, sizeof(info)) )
             return -EFAULT;
         return 0;
     }
     
+    case XENVER_parameters:
+    {
+        xen_parameters_info_t info = { .virt_start = HYPERVISOR_VIRT_START };
+
+        if ( copy_to_user(arg, &info, sizeof(info)) )
+            return -EFAULT;
+        return 0;
+        
+    }
+    
     case XENVER_changeset:
     {
         xen_changeset_info_t chgset;
index 508ba6779aba51e4df9c6792de7e43e8f5a3e1ab..83fda53e1e9212db9e3a7fa7e83f8676a179b958 100644 (file)
@@ -213,6 +213,7 @@ typedef struct {
     u32      cpu_khz;
     unsigned long total_pages;
     unsigned long free_pages;
+    u32      hw_cap[8];
 } dom0_physinfo_t;
 
 /*
index d36986741688b7ba891dfc405eec0ff94b9dec35..bc3ced3660e156af16f7f0806a3ddde299c9f396 100644 (file)
@@ -30,11 +30,15 @@ typedef struct xen_compile_info {
 
 #define XENVER_capabilities 3
 typedef struct xen_capabilities_info {
-    int pae;
-    int arch;
+    char caps[1024];
 } xen_capabilities_info_t;
 
 #define XENVER_changeset 4
 typedef char xen_changeset_info_t[64];
 
+#define XENVER_parameters 5
+typedef struct xen_paramaters_info {
+unsigned long virt_start;
+} xen_parameters_info_t;
+
 #endif /* __XEN_PUBLIC_VERSION_H__ */